import requests
import json

from models.base import Base


class Review(Base):
    localTable = "reviews"

    @classmethod
    def createFromRow(self, data):
        review = Review()
        review.setId(data[0])
        review.setGameId(data[1])
        review.setAuthor(data[2])
        review.setRating(data[3])
        review.setBody(data[4])
        return review

    @classmethod
    def createFromJson(self, json):
        review = Review()
        if "id" in json:
            review.setId(json["id"])
        review.setGameId(json["game_id"])
        review.setAuthor(json["author"])
        review.setRating(json["rating"])
        review.setBody(json["body"])
        return review

    # Returns the global remote path ("index")
    @classmethod
    def getIndexPath(self):
        return "%s/reviews" % self.remoteBase

    # Returns the remote path for a single game ("show")
    @classmethod
    def getShowPath(self, game):
        return "%s/games/%d/reviews" % (self.remoteBase, game.getId())

    @classmethod
    def save(self, review):
        self.connectToDatabase()

        c = self.conn.cursor()
        if not review.hasId():
            c.execute("""INSERT INTO reviews (game_id, author, rating, body)
                      VALUES (?, ?, ?, ?)""",
                      (review.getGameId(), review.getAuthor(),
                       review.getRating(), review.getBody(),))
        else:
            c.execute("""UPDATE reviews SET game_id = ?, author = ?,
                      rating = ?, body = ? WHERE id = ?""",
                      (review.getGameId(), review.getAuthor(), review.getRating(),
                       review.getBody(), review.getId(),))
        self.conn.commit()

    @classmethod
    def submitRemote(self, review, game):
        url = Review.getShowPath(game)
        review.setGameId(game.getId())
        print(url)
        resp = requests.post(url, data=json.dumps(review.getSubmitAttributes()))
        print(resp.text)

    @classmethod
    def getByGameId(self, gameId):
        self.connectToDatabase()

        c = self.conn.cursor()
        models = []

        # Get the models
        for data in c.execute(("""SELECT * FROM %s WHERE game_id = ?
                               ORDER BY id""" % self.localTable), (gameId,)):
            models.append(self.createFromRow(data))

        return models

    @classmethod
    def updateRemoteByParent(self, games):
        for game in games:
            url = self.getShowPath(game)
            resp = self.fetchRemoteContent(url)
            json = resp.json()
            objs = []
            for obj in json:
                objs.append(self.createFromJson(obj))
            for obj in objs:
                self.save(obj)

    # Setters and getters
    def setId(self, idn):
        self.idn = idn
        return self

    def getId(self):
        return self.idn

    def hasId(self):
        return hasattr(self, "idn")

    def setGameId(self, gameId):
        self.gameId = gameId
        return self

    def getGameId(self):
        return self.gameId

    def setAuthor(self, author):
        self.author = author
        return self

    def getAuthor(self):
        return self.author

    def setRating(self, rating):
        self.rating = rating
        return self

    def getRating(self):
        return self.rating

    def setBody(self, body):
        self.body = body
        return self

    def getBody(self):
        return self.body

    # Used for brief attributes in GET /games
    def getAttributes(self):
        return {
            "id": self.getId(),
            "game_id": self.getGameId(),
            "author": self.getAuthor(),
            "rating": self.getRating(),
            "body": self.getBody()
        }

    def getSubmitAttributes(self):
        return {
            "game_id": self.getGameId(),
            "author": self.getAuthor(),
            "rating": self.getRating(),
            "body": self.getBody()
        }

    # Used for all attributes in GET /games/:game_id:
    def getAllAttributes(self):
        return self.getAttributes()

    # Used for testing
    @classmethod
    def getMocks(self):
        reviews = []
        reviews.append(Review())
        reviews[0].setId(1)
        reviews[0].setGameId(1)
        reviews[0].setAuthor("Austin")
        reviews[0].setRating(5)
        reviews[0].setBody("Great game, would play again!")
        return reviews
